/***
 * @file IContext.h
 *
 *  @Author: calle
 *  @date Apr 10, 2011
 *  
 *  @brief Context Interface
 *
 *
 */

/**
 * \defgroup Context Context classes
 */

/**
 * \class IContext IContext.h <Generator/context/IContext.h>
 *
 * \brief Context interface.
 *
 * All the context needs to inherit from this class.
 * a decorator pattern is used to implement context.
 *
 * \ingroup Interfaces
 * \ingroup Context
 *
 * \todo Move to interface directory
 */
#ifndef ICONTEXT_H_
#define ICONTEXT_H_

#include <AbsSyn/Ident.h>
#include <Generator/context/IdentCmp.h>
#include <map>
#include <vector>
#include <AbsSyn/GenExpClasses/ExpressionType.h>
#include <boost/shared_ptr.hpp>
#include <AbsSyn/TypeEnum.h>

using namespace std;



class IContext {
public:
	typedef boost::shared_ptr<IContext *> IContextPtr;
	typedef vector< Ident > TypeList;
	virtual ~IContext(){};
	/**
	 * \brief check whether an identification exists
	 *
	 * when about to add a new variable its crucial that it be checked by
	 * the context, this check will do a validation if the identification exists.
	 * In case the ident exists this method will return true.
	 *
	 * @param ident
	 * @return true if identification variable is ok
	 */
	virtual bool identExists(const Ident& ident) const =0;
	/**
	 * \brief adds an new variable to the specific context.
	 *
	 * Adds a new variable identification of a certain type to the context.
	 * In case of success true is returned otherwise false. Most obvious
	 * reason for not adding a variable is the clashing instance of the same name.
	 *
	 * @param type
	 * @param ident
	 * @return true on success otherwise false
	 */
	virtual bool addIdent(TypeEnum type,const Ident& ident) =0;
	/**
	 * \brief remove a variable identification from the context.
	 *
	 * Remove the identification variable from the context.
	 *
	 * @param ident
	 * @return
	 */
	virtual bool removeIdent(const Ident& ident)=0;

	/**
	 * \brief finds the type for an identification
	 *
	 * Returns the type for an variable identification.
	 * in case the identification don't exist NULL is returned.
	 * Since the return type is a clone, it is up to the caller
	 * to release returned type.
	 *
	 *
	 * @param ident
	 * @return Type of identification
	 */
	virtual bool findType(const Ident& ident,TypeEnum& type)const =0;

	/**
	 * \brief Check context for all occurrences of a specific type
	 *
	 * Check the context for all occurrences of a specific type and
	 * add the identification to the list. This is used to retrieve a list
	 * of all occurrences of a certain type in the context.
	 *
	 * @param type which should be checked
	 * @param list with all the identifications matching the type.
	 */

	virtual void getAllOfType(TypeEnum type, IContext::TypeList& list) const=0;

	/**
	 * \brief get the parent context
	 *
	 * Forces all the context types to have a getParent method.
	 * The method will return the  parent for that context.
	 * If the context is root and has no parent NULL will be returned.
	 *
	 * @return Parent context
	 */
	virtual IContext* getParent() const =0;




	typedef map< Ident, TypeEnum, IdentCmp > CONTEXT_MAP;


};

#endif /* ICONTEXT_H_ */
